package net.mysoft.budgetsoft.system.service.impl;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import net.mysoft.budgetsoft.system.dao.FlowDao;
import net.mysoft.budgetsoft.system.dao.FlowTaskNodeDao;
import net.mysoft.budgetsoft.system.dao.FlowTemplateNodeDao;
import net.mysoft.budgetsoft.system.domain.TFlowNodeClass;
import net.mysoft.budgetsoft.system.domain.TFlowTaskNode;
import net.mysoft.budgetsoft.system.domain.TFlowTemplate;
import net.mysoft.budgetsoft.system.domain.TFlowTemplateNode;
import net.mysoft.budgetsoft.system.domain.TYongHu;
import net.mysoft.budgetsoft.system.pagemodel.FlowTaskNode;
import net.mysoft.budgetsoft.system.pagemodel.FlowTemplateNode;
import net.mysoft.budgetsoft.system.pagemodel.YongHu;
import net.mysoft.budgetsoft.system.service.FlowTemplateNodeService;
import net.mysoft.framework.model.DataGrid;
import net.mysoft.framework.model.SessionInfo;
import net.mysoft.framework.util.ResourceUtil;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

/**   
 *  
 * @author dagongPGP v1.0 
 * @link <a href=http://www.dagongsoft.net>北京大公信软科技有限公司</a> 
 *  
 * @version $Revision: 1.00  $Date: 2013-07-08 17:28:18 
 */
@Service("flowTemplateNodeService")
public class FlowTemplateNodeServiceImpl implements FlowTemplateNodeService{
	private static final Logger logger = Logger.getLogger(FlowTemplateNodeServiceImpl.class);

	
	@Resource
	private FlowTemplateNodeDao flowTemplateNodeDao;
	//@Resource
	private FlowDao flowDao;
	//@Resource
	private FlowTaskNodeDao flowTaskNodeDao;
	
	public FlowTaskNodeDao getFlowTaskNodeDao() {
		return flowTaskNodeDao;
	}

	public void setFlowTaskNodeDao(FlowTaskNodeDao flowTaskNodeDao) {
		this.flowTaskNodeDao = flowTaskNodeDao;
	}

	public FlowDao getFlowDao() {
		return flowDao;
	}

	public void setFlowDao(FlowDao flowDao) {
		this.flowDao = flowDao;
	}

	public FlowTemplateNodeDao getFlowTemplateNodeDao(){
		return this.flowTemplateNodeDao;
	}
	
	public void setFlowTemplateNodeDao(FlowTemplateNodeDao flowTemplateNodeDao){
		this.flowTemplateNodeDao = flowTemplateNodeDao;
	}
	
	
	/**
	 * 根据指定元素查找BaseProperties元素
	 * @param element
	 * @author zhouying
	 */
	private Element getElement(Element element) {
		String str = "BaseProperties";
		for (Iterator iter = element.elementIterator(); iter.hasNext();) {
			Element elementInner = (Element) iter.next();
			String attrib = elementInner.getName();
			if (!str.equals(attrib)) {
				elementInner = getElement(elementInner);
				if (elementInner != null)
					return elementInner;
			} else {
				// this.flowId1=elementInner.attribute("flowId").getValue();
				this.returnElement = elementInner;
				return elementInner;
			}
		}
		return null;
	}
	Element returnElement;
	  
	@Override
	public void parseXMLAndSave(FlowTemplateNode flowTemplateNode) throws Exception {
		//System.out.println("解析并保存");
		String strFlowXML = ServletActionContext.getRequest().getParameter("FlowXML1");//以，字符串形式获取.XML文件内容		
		String strFlowSetID = ServletActionContext.getRequest().getParameter("FlowSetID");//获取流程模板ID		
		String strFlowSetName = ServletActionContext.getRequest().getParameter("FlowSetName");//获取流程模板名称
		String strStatus = ServletActionContext.getRequest().getParameter("Status");//获取节点状态，状态分为开始节点、普通节点和结束节点				
		String strFL_ID = ServletActionContext.getRequest().getParameter("FL_ID");//获取流程类型ID
		////System.out.println("strFlowXML1" + strFlowXML);
				
		Document document = DocumentHelper.parseText(strFlowXML);//采用dom4j解析方法进行解析		
		Element elem = document.getRootElement();//获取document的根节点
		String eleName = elem.getName();

		getElement(elem);
		this.returnElement.setAttributeValue("flowId", strFlowSetID);//获取流程模板ID
		this.returnElement.setAttributeValue("flowText", strFlowSetName);//获取流程模板名称
		////System.out.println(this.returnElement.getName());		
		String flowId = this.returnElement.attribute("flowId").getValue();
		String flowText = this.returnElement.attribute("flowText").getValue();
		flowId = strFlowSetID;
		flowText = strFlowSetName;
		////System.out.println(flowId + "flowId");
		////System.out.println(flowText + "flowText");
		
		String path = ServletActionContext.getRequest().getRealPath("/");
		//System.out.println("path=" + path);
		PrintStream out = new PrintStream(path + "/" + "platform/WebFlow/flows/" + flowId + ".xml","utf-8");//将XML文件存到指定路径下

		document.setXMLEncoding("utf-8");
		strFlowXML = document.asXML();
		String xml = document.asXML();//将文档装换成XML
		out.println(xml);
		out.flush();
		out.close();
		//addOption2Main(path, flowId + ".xml", flowText);
		addXML2DB(document, flowId, flowText);//核心方法，实现将数据从XML到DB
//
//		String conditions = "1=1";
//		BLRfFlowSetFacade facade = new BLRfFlowSetFacade();
//		conditions += " and FL_ID = '" + strFL_ID + "'";
//		Collection col = facade.findByConditions(conditions.toString());//实现对流程模板的状态改变，是否已启用
//		ArrayList dtoList = new ArrayList();
//		dtoList.addAll(col);
//		request.setAttribute("Conditions", conditions.toString());
//		request.setAttribute("dtoList", dtoList);
//		request.setAttribute("FL_ID", strFL_ID.toString());
		
	}
	
	/**
	 * 实现将XML中全部元素属性及值存储到数据库中（流程设计核心方法）
	 * @param document（流程图解析后形成document）,flowid（流程模板ID）,flowText(流程模板名称)
	 * @throws Exception 
	 * @author zhouying
	 */
	public void addXML2DB(Document document, String flowId, String flowText) throws Exception {
		TFlowTemplate tFlowTemplate = (TFlowTemplate) flowTemplateNodeDao.load(TFlowTemplate.class, flowId);//流程模板
		if(flowId!=null&&!"".equals(flowId)){//删除模板下的节点
			//flowTemplateNodeDao.executeHql("delete TFlowTemplateNode t where t.flowTemplate.ftl_ID = ?",new String[]{flowId});
			List list =flowTemplateNodeDao.find("from TFlowTemplateNode t where t.flowTemplate.ftl_ID = ?",new String[]{flowId});
			flowTemplateNodeDao.delete(list);
		}
		Element root = document.getRootElement();//获取根元素
		Element steps = root.element("Steps");//获取总体步骤节点元素，在此元素下可以遍历所有步骤节点
		Element actions = root.element("Actions");//获取总体连接线节点元素，在此元素下可以遍历所有连接线节点

        //通过对连接线进行遍历，可以获得连接线上的开始步骤节点和结束步骤节点
		if (actions != null && actions.elements().size() > 0) {
			List actionList = actions.elements("Action");
			String begin = getBegin(actionList).attributeValue("from");// 得到初始节点
			ArrayList<Element> ends = (ArrayList<Element>) getEnd(actionList);//得到末尾节点
			// String end = getEnd(actionList).get(0).attributeValue("to");//
			// 得到末尾节点 （已经改写）
			if (steps != null && steps.elements().size() > 0) {
				List stepsList = steps.elements("Step");
				// 处理开始节点将其单独存入数据库
				Element beginelement = getStep(stepsList, begin);//得到开始节点的所有属性
				
				TFlowTemplateNode beginTFlowTemplateNode = new TFlowTemplateNode();
				if (beginelement != null) {
					String beginid = beginelement.attributeValue("id");//开始节点ID
					String begintext = beginelement.attributeValue("text");//开始节点名称
					String begintype = beginelement.attributeValue("stepStatus");//节点状态（名称不太确切，应该是节点类型）
					String beginIndeptUserCode = beginelement.attributeValue("userCode");//节点接收人员
					String beginIndeptComCode = beginelement.attributeValue("comCode");//节点接收部门
					String beginIndeptRoleCode = beginelement.attributeValue("roleCode");//节点接收角色
					String beginDeadline = beginelement.attributeValue("deadline");//办理期限
					String beginRemindInterval = beginelement.attributeValue("remindInterval");//提醒间隔
					String detractCode = beginelement.attributeValue("detractCode");//分支条件
					String beginTextList = beginelement.attributeValue("textList");//节点绑定单个文本区域名称
					String beginFormUrl = beginelement.attributeValue("formUrl");//节点绑定单个按钮名称
		
					String beginFtn_XiangMuJD = beginelement.attributeValue("ftn_XiangMuJD");
					String beginFtn_Class= beginelement.attributeValue("ftn_Class");
					String beginFtn_UserNum = beginelement.attributeValue("ftn_UserNum");
					String beginFtn_MustPass = beginelement.attributeValue("ftn_MustPass");
					String beginFtn_ReturnTo = beginelement.attributeValue("ftn_ReturnTo");
//					if (flowTemplateNode.findByPrimaryKey1(beginid, flowId) == null) {
//					} else
//						flowTemplateNode.delete(beginid, flowId);
					//构造流程模板节点实体属性
					
					beginTFlowTemplateNode.setFtn_ID(flowId+"."+beginid);
					beginTFlowTemplateNode.setFlowTemplate(tFlowTemplate);
					beginTFlowTemplateNode.setFtn_Index(0);//流程节点模板索引
					beginTFlowTemplateNode.setFtn_Name_cn(begintext);
					beginTFlowTemplateNode.setFtn_IndeptUserCode(beginIndeptUserCode);
					beginTFlowTemplateNode.setFtn_IndeptComCode(beginIndeptComCode);
					beginTFlowTemplateNode.setFtn_IndeptRoleCode(beginIndeptRoleCode);
					beginTFlowTemplateNode.setFtn_Deadline(beginDeadline);
					beginTFlowTemplateNode.setFtn_RemindInterval(beginRemindInterval);
					beginTFlowTemplateNode.setFtn_DetractCode(detractCode);
					beginTFlowTemplateNode.setFtn_TextName(beginTextList);
					beginTFlowTemplateNode.setFtn_FormUrl(beginFormUrl);
					beginTFlowTemplateNode.setFtn_PID("0");//设置父节点ID为0
					if(beginFtn_Class!=null&&!"".equals(beginFtn_Class)){
						beginTFlowTemplateNode.setFlowNodeClass((TFlowNodeClass) flowTemplateNodeDao.load(TFlowNodeClass.class, beginFtn_Class));
					}
					if(beginFtn_MustPass!=null&&!"".equals(beginFtn_MustPass)){
						beginTFlowTemplateNode.setFtn_MustPass(Integer.parseInt(beginFtn_MustPass));
					}
					if(beginFtn_UserNum!=null&&!"".equals(beginFtn_UserNum)){
						beginTFlowTemplateNode.setFtn_UserNum(Integer.parseInt(beginFtn_UserNum));
					}
					if(beginFtn_ReturnTo!=null&&!"".equals(beginFtn_ReturnTo)){
						beginTFlowTemplateNode.setFtn_ReturnTo(flowId+"."+beginFtn_ReturnTo);
					}
					if (beginFtn_XiangMuJD!=null&&!"".equals(beginFtn_XiangMuJD)) {
						beginTFlowTemplateNode.setFtn_XiangMuJD(Integer.parseInt(beginFtn_XiangMuJD));
					}
					if (begintype == null) {
						begintype = "0";
						beginTFlowTemplateNode.setFtn_Type(Integer.parseInt(begintype));
					} else
						beginTFlowTemplateNode.setFtn_Type(Integer.parseInt(begintype));//开始节点类型为0
					beginTFlowTemplateNode.setFtn_State(1);//开始节点状态为1
					flowTemplateNodeDao.save(beginTFlowTemplateNode);

				}
				//处理开始节点将其单独存入数据库
                //处理除开始节点以外的所有节点
				List<String> list = new ArrayList<String>();
				for (int j = 0; j < actionList.size(); j++) {
					Element action = (Element) actionList.get(j);
					Element baseProperties = action.element("BaseProperties");
					String to1 = baseProperties.attributeValue("to");
					list.add(to1);
				}
				Map<String, String> map = new HashMap<String, String>();
				int k = 0;
				
				List<TFlowTemplateNode> ftnList = new ArrayList<TFlowTemplateNode>();
				for (String s : list) {
					map.put(s, gettofrom(actionList, s));
					Element step = getStep(stepsList, s);
					String idt = step.attributeValue("id");
					String textt = step.attributeValue("text");
					String stepStatust = step.attributeValue("stepStatus");
					String indeptUserCode = step.attributeValue("userCode");
					String indeptComCode = step.attributeValue("comCode");
					String indeptRoleCode = step.attributeValue("roleCode");
					String deadline = step.attributeValue("deadline");
					String remindInterval = step.attributeValue("remindInterval");
					String detractCode = step.attributeValue("detractCode");
					String textList = step.attributeValue("textList");
					String formUrl = step.attributeValue("formUrl");
					String ftn_XiangMuJD = step.attributeValue("ftn_XiangMuJD");
					String ftn_Class= step.attributeValue("ftn_Class");
					String ftn_UserNum = step.attributeValue("ftn_UserNum");
					String ftn_MustPass = step.attributeValue("ftn_MustPass");
					String ftn_ReturnTo = step.attributeValue("ftn_ReturnTo");
					
					// 分支流程有待修改，设置流程节点状态
//					if (flowTemplateNode.findByPrimaryKey1(idt, flowId) == null) {
//					} else
//						flowTemplateNode.delete(idt, flowId);
					TFlowTemplateNode tFlowTemplateNode = new TFlowTemplateNode();
					tFlowTemplateNode.setFtn_ID(flowId+"."+idt);
					tFlowTemplateNode.setFlowTemplate(tFlowTemplate);
					tFlowTemplateNode.setFtn_Index(k + 1);
					tFlowTemplateNode.setFtn_Name_cn(textt);
					tFlowTemplateNode.setFtn_IndeptUserCode(indeptUserCode);
					tFlowTemplateNode.setFtn_IndeptComCode(indeptComCode);
					tFlowTemplateNode.setFtn_IndeptRoleCode(indeptRoleCode);
					tFlowTemplateNode.setFtn_Deadline(deadline);
					tFlowTemplateNode.setFtn_RemindInterval(remindInterval);
					tFlowTemplateNode.setFtn_DetractCode(detractCode);
					tFlowTemplateNode.setFtn_TextName(textList);
					tFlowTemplateNode.setFtn_FormUrl(formUrl);
					if(ftn_Class!=null&&!"".equals(ftn_Class)){
						tFlowTemplateNode.setFlowNodeClass((TFlowNodeClass) flowTemplateNodeDao.load(TFlowNodeClass.class, ftn_Class));
					}
					if(ftn_UserNum!=null&&!"".equals(ftn_UserNum)){
						tFlowTemplateNode.setFtn_UserNum(Integer.parseInt(ftn_UserNum));
					}
					if(ftn_MustPass!=null&&!"".equals(ftn_MustPass)){
						tFlowTemplateNode.setFtn_MustPass(Integer.parseInt(ftn_MustPass));
					}
					if(ftn_ReturnTo!=null&&!"".equals(ftn_ReturnTo)){
						tFlowTemplateNode.setFtn_ReturnTo(flowId+"."+ftn_ReturnTo);
					}
					
					if (ftn_XiangMuJD!=null&&!"".equals(ftn_XiangMuJD)) {
						tFlowTemplateNode.setFtn_XiangMuJD(Integer.parseInt(ftn_XiangMuJD));
					}
					String pid = gettofrom(actionList, s);
					String pids = "";
					if(pid!=null&&pid.indexOf(",")>0){
						String[] pidArr = pid.split(",");
						for(int i=0;i<pidArr.length;i++){
							if(i>0)pids+=",";
							pids+=flowId+"."+pidArr[i];
						}
					}else{
						pids = flowId+"."+pid;
					}
					tFlowTemplateNode.setFtn_PID(pids);
					if (stepStatust == null) {
						stepStatust = "0";
						tFlowTemplateNode.setFtn_Type(Integer.parseInt(stepStatust));//普通节点类型为0
					} else
						tFlowTemplateNode.setFtn_Type(Integer.parseInt(stepStatust));
					// TODO 判断当前节点是否在末尾节点的List中
					boolean isEnd = false;
					//分支流程结束节点不止一个
					for (int r = 0; r < ends.size(); r++)
						if (idt.equals(ends.get(r).attributeValue("to"))) {
							tFlowTemplateNode.setFtn_State(2);
							isEnd = true;
							break;
						}
					if (!isEnd)
						tFlowTemplateNode.setFtn_State(0);
		
					ftnList.add(tFlowTemplateNode);
					k += 1;
				}
				
				
				//排序
				int index = 1;//如果 tFlowTemplateNode 没有子节点break 如果有
				List tempList = new ArrayList();
				tempList.add(beginTFlowTemplateNode);
				while(true){
					List<TFlowTemplateNode> lll = findChildTemplateNode(tempList,ftnList);
					if(lll.size()==0){
						break;
					}else{
						for(TFlowTemplateNode tt:lll){
							tempList = lll;
							tt.setFtn_Index(index);
							index++;
						}
					}
				}
				for(TFlowTemplateNode tFlowTemplateNode:ftnList){
					flowTemplateNodeDao.save(tFlowTemplateNode);
				}
			}
		}
	}
	
	private List findChildTemplateNode(List<TFlowTemplateNode> list,List<TFlowTemplateNode> allList){
		List childList = new ArrayList();
		for(TFlowTemplateNode fff:list){
			for(TFlowTemplateNode ftn2:allList){
				if(ftn2.getFtn_PID()!=null&&ftn2.getFtn_PID().indexOf(fff.getFtn_ID())>=0){
					childList.add(ftn2);
				}
			}
		}
		return childList;
	}
	
	/**
	 * 根据连接线连接的开始节点，即from节点，得到步骤的子节点
	 * @param stepsList,from
	 * @author zhouying
	 */
	private Element getStep(List stepsList, String from) {
		Element stepElement = null;
		for (int i = 0; i < stepsList.size(); i++) {
			Element step = (Element) stepsList.get(i);
			Element baseProperties = step.element("BaseProperties");//获取指定名称的元素
			//			//System.out.println("getStepactionbaseProperties.getName()" + baseProperties.getName());
			String from1 = baseProperties.attributeValue("id");

			if (from1.equals(from))
				stepElement = baseProperties;
		}
		return stepElement;
	}
	/**
	 * 根据连接线连接的结束节点，即to节点，得到连接线的开始节点，即from节点
	 * @param stepsList,from
	 * @author zhouying
	 */
	private String gettofrom(List actionList, String to) {
		String tot = "";
		for (int i = 0; i < actionList.size(); i++) {
			Element action = (Element) actionList.get(i);
			Element baseProperties = action.element("BaseProperties");
			//			//System.out.println("gettofromactionbaseProperties.getName()" + baseProperties.getName());
			String to1 = baseProperties.attributeValue("to");
			if (to1.equals(to))
				tot += baseProperties.attributeValue("from") + ",";
		}
		if (tot.equals("")) {
		} else
			tot = tot.substring(0, tot.length() - 1);
		return tot;
	}
	/**
	 * 根据连接线节点集合，返回末尾节点，分支节点末尾节点不只一个。
	 * 对to节点进行遍历，若是在所有from节点中都不存在，则证明是末尾节点
	 * @param actionList 
	 * @author zhouying
	 */
	private List<Element> getEnd(List actionList) {// It is method for getting end node
		String end = "";
		String endfrom = "";
		List<Element> elements = new ArrayList<Element>();
		Element base = null;
		for (int i = 0; i < actionList.size(); i++) {
			Element action = (Element) actionList.get(i);
			Element baseProperties = action.element("BaseProperties");
			//			//System.out.println("getendactionbaseProperties.getName()" + baseProperties.getName());
			String to = baseProperties.attributeValue("to");
			////System.out.println("to" + to);
			int count = 0;
			for (int j = 0; j < actionList.size(); j++) {
				Element actionj = (Element) actionList.get(j);
				Element basePropertiesj = actionj.element("BaseProperties");
				////System.out.println("getend2actionbaseProperties.getName()" + basePropertiesj.getName());
				String from = basePropertiesj.attributeValue("from");

				if (!to.equals(from)) {
					////System.out.println("getendfrom" + from);
					count += 1;
				}
			}

			////System.out.println("actionList.size()" + actionList.size());
			////System.out.println("countend" + count);
			if (count == actionList.size()) {//判断是否所有from节点都不存在这个to节点
				end = to;
				base = baseProperties;
				elements.add(base);
			}

		}
		//测试方法
		for (int i = 0; i < elements.size(); i++) {
			end = elements.get(i).attributeValue("to");
			endfrom = elements.get(i).attributeValue("from");
			////System.out.println("end:" + end);
			////System.out.println("endto:" + endfrom);
		}

		return elements;
	}
	/**
	 * 根据连接线节点集合，返回开始节点，开始节点只有一个。
	 * 对from节点进行遍历，若是在所有to节点中都不存在，则证明是开始节点
	 * @param actionList 
	 * @author zhouying
	 */
	private Element getBegin(List actionList) {
		String begin = "";
		Element base = null;
		for (int i = 0; i < actionList.size(); i++) {// 判断第一个节点
			Element action = (Element) actionList.get(i);
			Element baseProperties = action.element("BaseProperties");
			//			//System.out.println("actionbaseProperties.getName()" + baseProperties.getName());
			String from = baseProperties.attributeValue("from");
			//			//System.out.println("from" + from);
			int count = 0;
			for (int j = 0; j < actionList.size(); j++) {
				Element actionj = (Element) actionList.get(j);
				Element basePropertiesj = actionj.element("BaseProperties");
				//				//System.out.println("actionbaseProperties.getName()" + basePropertiesj.getName());
				String to = basePropertiesj.attributeValue("to");

				if (!from.equals(to)) {
					//					//System.out.println("to" + to);
					count += 1;
				}

			}

			//			//System.out.println("actionList.size()" + actionList.size());
			//			//System.out.println("count" + count);
			if (count == actionList.size()) {
				begin = from;
				base = baseProperties;
				break;
			}

		}
		//		//System.out.println("begin" + begin);

		return base;
	}
	/**
	 * 判断某个元素的属性值是否相同
	 * @param Element select, String value, String text
	 * @author zhouying
	 */
	private boolean getDiff(Element select, String value, String text) {
		List options = select.elements();
		for (int i = 0; i < options.size(); i++) {
			Element opt = (Element) options.get(i);
			if (opt.attributeValue("value").equals(value))
				return false;
		}
		return true;
	}
	/**
	 * 筛选value相同，text不同的元素
	 * @param Element select, String value, String text
	 * @author zhouying
	 */
	private Element getText(Element select, String value, String text) {
		List options = select.elements();
		for (int i = 0; i < options.size(); i++) {
			Element opt = (Element) options.get(i);
			if (opt.attributeValue("value").equals(value))
				if (!opt.attributeValue("text").equals(text))
					return opt;
		}
		return null;
	}
	/**
	 * 筛选value相同，text不同的元素
	 * @param Element select, String value, String text
	 * @return boolean
	 * @author zhouying
	 */
	private boolean getBool(Element select, String value, String text) {
		List options = select.elements();
		for (int i = 0; i < options.size(); i++) {
			Element opt = (Element) options.get(i);
			if (opt.attributeValue("value").equals(value))
				if (!opt.attributeValue("text").equals(text))
					return true;
		}
		return false;
	}
	@Override
	public void add(FlowTemplateNode flowTemplateNode){
		TFlowTemplateNode t = new TFlowTemplateNode();
		BeanUtils.copyProperties(flowTemplateNode, t);
		//t.setFtn_ID(UUID.randomUUID().toString());
		flowTemplateNodeDao.save(t);
	}
	
	@Override
	public void edit(FlowTemplateNode flowTemplateNode){
		TFlowTemplateNode t = new TFlowTemplateNode();
		BeanUtils.copyProperties(flowTemplateNode, t);
		flowTemplateNodeDao.update(t);
	}
	
	@Override
	public void delete(FlowTemplateNode flowTemplateNode) {
		for (String id : flowTemplateNode.getIds().split(",")) {
			Object t =  flowTemplateNodeDao.get(TFlowTemplateNode.class, id);
			if (t != null) {
				 flowTemplateNodeDao.delete(t);
			}
		}
	}
	
	@Override
	public DataGrid datagrid(FlowTemplateNode flowTemplateNode){
		DataGrid dg = new DataGrid();
		String hql = "from TFlowTemplateNode t where 1=1 ";
		List params = new ArrayList();
		hql = addWhere(flowTemplateNode, hql, params);
		String totalHql = "select count(*) " + hql;
		hql = addOrder(flowTemplateNode, hql);
		List<TFlowTemplateNode> toList = flowTemplateNodeDao.find(hql, params, flowTemplateNode.getPage(), flowTemplateNode.getRows());
		List<FlowTemplateNode> oList = new ArrayList<FlowTemplateNode>();
		oList = changeModel(toList);
		dg.setTotal(flowTemplateNodeDao.count(totalHql, params));
		dg.setRows(oList);
		return dg;
	}
	
	private String addWhere(FlowTemplateNode flowTemplateNode, String hql, List<Object> params) {
//	if(flowTemplateNode.getXiangMuJBXXBH()!=null&&!"".equals(flowTemplateNode.getXiangMuJBXXBH())){
//		hql+=" and t.flowTemplate.ftl_ID in (select ftl_ID TXiangMuFlow as xf where xf.xiangMuBH = ?)";
//		params.add(flowTemplateNode.getXiangMuJBXXBH());
//	}
//	if(flowNode.getRenWuJBXXBH()!=null&&!"".equals(flowNode.getRenWuJBXXBH())){
//		hql+=" and t.renWuJBXX.bianHao = ?";
//		params.add(flowNode.getRenWuJBXXBH());
//	}
//	if(flowNode.getFln_Status()!=null){
//		hql+=" and t.fln_Status = ?";
//		params.add(flowNode.getFln_Status());
//	}
//	if(flowNode.getFln_UserCode()!=null){
//		SessionInfo sessionInfo = (SessionInfo) ServletActionContext.getRequest().getSession().getAttribute(ResourceUtil.getSessionInfoName());
//		if(sessionInfo.getRoleIds().indexOf(ResourceUtil.ADMIN_ROLE_ID)<0){
//			hql+=" and t.fln_UserCode like ?";
//			params.add("%"+flowNode.getFln_UserCode()+"%");
//		}
//	}
	if(flowTemplateNode.getFtl_ID()!=null&&!"".equals(flowTemplateNode.getFtl_ID())){
		boolean first = true;
		hql+=" and t.flowTemplate.ftl_ID in (";
		for(String ftl_ID : flowTemplateNode.getFtl_ID().split(",")) {
			if(first) {
				hql += "?";
				params.add(ftl_ID);
				first = false;
			}else{
				hql += ",?";
				params.add(ftl_ID);
			}
		}
		hql+=")";
	}
	if(flowTemplateNode.getFtn_Class()!=null){
		boolean first = true;
		hql+=" and t.flowNodeClass.fnc_ID in(";
		for(String fnc_ID : flowTemplateNode.getFtn_Class().split(",")) {
			if(first) {
				hql += "?";
				params.add(fnc_ID);
				first = false;
			}else{
				hql += ",?";
				params.add(fnc_ID);
			}
		}
		hql+=")";
	}
	
	return hql;
}
	
	private String addOrder(FlowTemplateNode flowTemplateNode, String hql) {
		if (flowTemplateNode.getSort() != null) {
			hql += " order by " + flowTemplateNode.getSort() + " " + flowTemplateNode.getOrder();
		}
		return hql;
	}
	
	public List<FlowTemplateNode> changeModel(List<TFlowTemplateNode> tFlowTemplateNode ){
		List<FlowTemplateNode> list = new ArrayList<FlowTemplateNode>();
		for(TFlowTemplateNode to:tFlowTemplateNode){
			FlowTemplateNode o = new FlowTemplateNode();
			BeanUtils.copyProperties(to, o);
			if(to.getFlowNodeClass()!=null){
				o.setFtn_Class(to.getFlowNodeClass().getFnc_ID());
			}
			list.add(o);
		}
		return list;
	}

	@Override
	public List<FlowTemplateNode> findNextFlowTemplateNode(String xiangMuJBXXBH,String ftc_ID) {
		/*TXiangMuJBXX tx = (TXiangMuJBXX) flowTemplateNodeDao.get(TXiangMuJBXX.class, xiangMuJBXXBH);
		List<TFlowTemplate_YeWuZL> list2 = flowTemplateNodeDao.find("from TFlowTemplate_YeWuZL as fy where fy.yeWuZLBH = ?",new String[]{tx.getYeWuZLWH().getBianHao()});
		for(TFlowTemplate_YeWuZL fy:list2){
			TFlowTemplate tft = (TFlowTemplate) flowTemplateNodeDao.get(TFlowTemplate.class, fy.getFtl_ID());
			if(tft.getFtc_ID().equals(ftc_ID)&&tft.getFtl_Valid()==1){
				List<TFlowTemplateNode> listt = flowTemplateNodeDao.find("from TFlowTemplateNode t where t.flowTemplate.ftl_ID = ? and t.ftn_State = 1",new String[]{tft.getFtl_ID()});
				if(listt.size()==1){
					TFlowTemplateNode tt = listt.get(0);
					List<TFlowTemplateNode> listt2 = flowTemplateNodeDao.find("from TFlowTemplateNode t where t.flowTemplate.ftl_ID = ? and t.ftn_PID = ? ",new String[]{tft.getFtl_ID(),tt.getFtn_ID()});
					return changeModel(listt2);
				}
			}
		}*/
		return null;
	}

	
	@Override
	public List<FlowTemplateNode> findMenu(FlowTemplateNode flowTemplateNode) {
		//List<TXiangMuFlow> list = flowTemplateNodeDao.find("from TXiangMuFlow as xf where xf.xiangMuBH = ?",new String[]{flowTemplateNode.getXiangMuJBXXBH()});
		String ftl_ID = "";
		/*for(TXiangMuFlow xf:list){
			if(!ftl_ID.equals("")){
				ftl_ID+=",";
			}
			ftl_ID+=xf.getFtl_ID();
		}*/
		flowTemplateNode.setFtl_ID(ftl_ID);
		String hql = "from TFlowTemplateNode t where 1=1 ";
		List params = new ArrayList();
		hql = addWhere(flowTemplateNode, hql, params);
		hql = addOrder(flowTemplateNode, hql);
		List<TFlowTemplateNode> toList = flowTemplateNodeDao.find(hql, params);
		List<FlowTemplateNode> oList = changeModel(toList);

		FlowTaskNode flowTaskNode =new FlowTaskNode();
		SessionInfo sessionInfo = (SessionInfo) ServletActionContext.getRequest().getSession().getAttribute(ResourceUtil.getSessionInfoName());
		flowTaskNode.setFtn_UserCode(sessionInfo.getUserId());
		flowTaskNode.setFtn_Status(1);
		flowTaskNode.setFtn_Class(flowTemplateNode.getFtn_Class());  
		flowTaskNode.setXiangMuJBXXBH(flowTemplateNode.getXiangMuJBXXBH());
		List<TFlowTaskNode> flowTaskNodeList = flowTaskNodeDao.find(flowTaskNode,null,null,null,null);//当前项目 当前人的待办任务
		
		String ftn_ID = null;
		for(TFlowTaskNode ftn:flowTaskNodeList){
			for(FlowTemplateNode fn:oList){
				if(fn.getFtn_ID().equals(ftn.getFlowTemplateNode().getFtn_ID())){//有ftn_ID  说明登录用户可以操作表单
					fn.setFtn_ID(ftn.getFtn_ID());
					ftn_ID = ftn.getFtn_ID();
					break;
				}
			}
		}
		for(FlowTemplateNode fn:oList){
			if(!fn.getFtn_ID().equals(ftn_ID)){
				fn.setFtn_ID(null);
			}
		}
		return oList;

	}

	@Override
	public List<FlowTemplateNode> findNextFlowTemplateNode(FlowTemplateNode flowTemplateNode) {
		return changeModel(flowDao.findNextFlowTemplateNodeByFtn_ID(flowTemplateNode.getFtn_ID(),flowTemplateNode.getLineStart()));
	}
	@Override
	public List<FlowTemplateNode> findBackFlowTemplateNode(FlowTemplateNode flowTemplateNode) {
		/*return changeModel(flowDao.findBackFlowTemplateNodeByFtn_ID(flowTemplateNode.getFtn_ID(),flowTemplateNode.getTemplateNode_ID()));*/
		return null;
	}
	
	@Override
	public List<YongHu> candidate(FlowTemplateNode flowTemplateNode) {
		logger.info("candidate:(flowTemplateNode.getTemplateNode_ID()="+flowTemplateNode.getTemplateNode_ID()+")  getFln_UserCode:="+flowTemplateNode.getFln_UserCode() +";xiangMuBH="+flowTemplateNode.getXiangMuBH());
		if(flowTemplateNode.getFln_UserCode()!=null&&!"".equals(flowTemplateNode.getFln_UserCode())){//如果指定人
			List<YongHu> list = new ArrayList();
			String[] userCodes = flowTemplateNode.getFln_UserCode().split(",");
			for(String userID:userCodes){
				TYongHu u = (TYongHu) flowDao.get(TYongHu.class, userID);
				if(u!=null){
					YongHu user = new YongHu();
					user.setBianHao(u.getBianHao());
					user.setXingMing(u.getXingMing());
					list.add(user);
				}
			}
			Set h = new HashSet(list);      
			list.clear();      
			list.addAll(h);
			return list;
		}else{
			List list = flowDao.candidate(flowTemplateNode.getTemplateNode_ID(),null);
			Set h = new HashSet(list);      
			list.clear();      
			list.addAll(h);
			return list;
		}
	}

	//@Override
	//public List<User> backUpCandidate(FlowTemplateNode flowTemplateNode) {
		/*System.out.println("backUpCandidate:"+flowTemplateNode.getFln_UserCode());
		if(flowTemplateNode.getFln_UserCode()!=null&&!"".equals(flowTemplateNode.getFln_UserCode())){//如果指定人
			List<User> list = new ArrayList();
			String[] userCodes = flowTemplateNode.getFln_UserCode().split(",");
			for(String userID:userCodes){
				TUser u = (TUser) flowDao.get(TUser.class, userID);
				if(u!=null){
					User user = new User();
					user.setUserID(u.getUserID());
					user.setUserName_cn(u.getUserName_cn());
					user.setUserName_en(u.getUserName_en());
					list.add(user);
				}
			}
			Set h = new HashSet(list);      
			list.clear();      
			list.addAll(h);
			return list;
		}else{
			List userList = flowDao.backUpCandidate(flowTemplateNode.getTemplateNode_ID(),flowTemplateNode.getFtn_ID());
			TFlowTaskNode ftn = (TFlowTaskNode) flowDao.get(TFlowTaskNode.class, flowTemplateNode.getFtn_ID());
			String xiangmubh = null;
			if(ftn!=null){
				xiangmubh = ftn.getXiangMuJBXXBH();
			}
			if(userList.size()==0&&xiangmubh!=null&&!"".equals(xiangmubh)){//没有指派人。并且没有备选人
				List<TXiangMuZCY> cyList = flowDao.find("from TXiangMuZCY t where t.xiangMuJBXX.xiangMuBH = ?",new String[]{xiangmubh}); 
				for(int x=0;x<cyList.size();x++){
					TXiangMuZCY t = cyList.get(x);
					TUser tuser = t.getUser();
					User user = new User();
					BeanUtils.copyProperties(tuser, user);
					userList.add(user);
				}
			}
			Set h = new HashSet(userList);      
			userList.clear();      
			userList.addAll(h);
			return userList;
		}*/
		//return null;
	//}

	
	/**
	 * 
	 */
	@Override
	public List<FlowTemplateNode> findFlowTemplateNodeByXMRW(FlowTemplateNode flowTemplateNode) {
		/*List<TFlowTaskNode_His> list_ftnhis = new ArrayList();
		String ftl_ID = "";
		if(flowTemplateNode.getXiangMuJBXXBH()!=null&&!"".equals(flowTemplateNode.getXiangMuJBXXBH())){
			FlowTaskNode ftn = new FlowTaskNode();
			ftn.setXiangMuJBXXBH(flowTemplateNode.getXiangMuJBXXBH());
			ftn.setFtn_Status(1);
			List<TFlowTaskNode> list = flowTaskNodeDao.find(ftn);
			if(list.size()>0){
				for(TFlowTaskNode tt:list){
					if(tt.getFlow().getFlowTemplate().getFtc_ID().equals("1")||tt.getFlow().getFlowTemplate().getFtc_ID().equals("2")){
						TFlowTemplateNode tn = tt.getFlowTemplateNode();
						ftl_ID = tn.getFlowTemplate().getFtl_ID();
						FlowTaskNode ftnq = new FlowTaskNode();
						ftnq.setXiangMuJBXXBH(flowTemplateNode.getXiangMuJBXXBH());
						ftnq.setFtn_Class("-1");
						list_ftnhis = flowTaskNodeDao.find_His(ftnq);
						break;
					}
				}
			}
		}else if(flowTemplateNode.getRenWuJBXXBH()!=null&&!"".equals(flowTemplateNode.getRenWuJBXXBH())){
			FlowTaskNode ftn = new FlowTaskNode();
			ftn.setRenWuJBXXBH(flowTemplateNode.getRenWuJBXXBH());
			ftn.setFtn_Status(1);
			List<TFlowTaskNode> list = flowTaskNodeDao.find(ftn);
			if(list.size()>0){
				TFlowTaskNode t = list.get(list.size()-1);
				TFlowTemplateNode tn = t.getFlowTemplateNode();
				ftl_ID = tn.getFlowTemplate().getFtl_ID();
				FlowTaskNode ftnq = new FlowTaskNode();
				ftnq.setRenWuJBXXBH(flowTemplateNode.getRenWuJBXXBH());
				list_ftnhis = flowTaskNodeDao.find_His(ftnq);
			}
		}
		Set<TFlowTemplateNode> set_ftn = new HashSet();
		for(TFlowTaskNode_His f:list_ftnhis){
			System.out.println(f.getFtn_Name_cn()+"@@@@@@@@@@"+f.getFlowTemplateNode().getFlowTemplate().getFtl_ID()+"@@@@@@"+ftl_ID);
			if(f.getFlowTemplateNode().getFlowTemplate().getFtl_ID().equals(ftl_ID)&&!f.getFlowTemplateNode().getFtn_Name_cn().equals("任务提交")){
				set_ftn.add(f.getFlowTemplateNode());
			}
		}
		System.out.println(set_ftn+"@@@@@@@@@@");
		return changeModel(new ArrayList(set_ftn));*/
		return null;
	}


	
//	public List<FlowTemplateNode> findNextTemplateFlowTemplateNode(FlowTemplateNode flowTemplateNode){ 
//		return changeModel(flowDao.findNextFlowTemplateNodeByRenWuJBXXBH(flowTemplateNode.getRenWuJBXXBH()));
//	}


}
